﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Temp.Model;
using Temp.Planner2;

namespace Temp.View
{
    class DialogueView
    {
        private Vector2 LEFTBARPOS = new Vector2(2, 730);
        private Vector2 RIGHTBARPOS = new Vector2(1135, 730);
        private Vector2 DIALOGUEBOXPOS = new Vector2(228, 518);
        private Vector2 CHAR1POS = new Vector2(7, 440);
        private Vector2 CHAR2POS = new Vector2(1140, 440);
        private Vector2 TEXTPOS = new Vector2(260, 553);
        private Vector2 CONTINUEPOS = new Vector2(975, 700);
        private Vector2 NAMEPLACERPOS = new Vector2(228, 476);

        public List<Conversation> listDialogue { get; set; }
        public bool isShowing;

        public Texture2D char1Pic { get; set; }
        public Texture2D char2Pic { get; set; }
        //public Planner planner { get;  set; } 
        private Texture2D dialogueBox;
        private Texture2D leftBar;
        private Texture2D rightBar;
        private Texture2D continueButton;
        private Texture2D arrowButton;
        private Texture2D namePlacer;
        private Rectangle continueRect;
        private bool continueButtonShowing;
        private bool inventGameFound; //flag for inventory or game dialogue found
        private SpriteFont calibri; //used for printing the text 

        private string currentDialogue; //dialogue of the one speaking
        private string currentSpeaker;  // name of the one speaking

        private MouseState mouse, mousePast;
        private Rectangle mouseBox;

        private EventPlanner eventPlanner;
        private AlexGame alexGame;
        private int timer = 0;

        struct optionRect
        {
            public List<Rectangle> optionRectangle;
            public string nameOfTriggerer;
            public string typeOfTriggerer;
            public List<string> optionName;
        };

        private List<optionRect> listOptionRect;

        /// <summary>
        /// Constructor for the DialogueView class
        /// </summary>
        /// <param name="eventPlanner">Instance of the EventPlanner class</param>
        /// <param name="alexGame">Instance of the AlexGame class</param>
        public DialogueView(EventPlanner eventPlanner, AlexGame alexGame)
        {
            this.eventPlanner = eventPlanner;
            this.alexGame = alexGame;
        }

        /// <summary>
        /// Initializes the variables needed by the DialogueView class
        /// </summary>
        public void Initialize()
        {
            isShowing = false;
            inventGameFound = false;
            continueButtonShowing = true;
            currentDialogue = " ";
            char1Pic = null;
            char2Pic = null;
            listDialogue = new List<Conversation>();
            listOptionRect = new List<optionRect>();


            mouseBox = new Rectangle(0, 0, 30, 30);
        }

        /// <summary>
        /// Loads the image for the peer
        /// </summary>
        /// <param name="content">Instance of the ContentManager class</param>
        /// <param name="gender">String used to indicate whether peer picked is a boy or a girl</param>
        public void LoadPeer(ContentManager content, String gender)
        {
            char1Pic = content.Load<Texture2D>("Peer/" + gender + "/peer");
        }

        /// <summary>
        /// Loads the images to be used by the DialogueView class
        /// </summary>
        /// <param name="content">Intance of the ContentManager class</param>
        public void LoadContent(ContentManager content)
        {

            dialogueBox = content.Load<Texture2D>("UI elements/storyBox");
            leftBar = content.Load<Texture2D>("UI elements/leftChar");
            rightBar = content.Load<Texture2D>("UI elements/rightChar");
            continueButton = content.Load<Texture2D>("UI elements/continue");
            arrowButton = content.Load<Texture2D>("UI elements/arrow");
            namePlacer = content.Load<Texture2D>("UI elements/namePlacer");
            calibri = content.Load<SpriteFont>("Calibri");

            continueRect = new Rectangle((int)CONTINUEPOS.X, (int)CONTINUEPOS.Y, continueButton.Width, continueButton.Height);
        }

        private int dListIndex = 0; //dialogue list index;

        /// <summary>
        /// Logic for the dialogue box. This checks whether the continue button or an option has been clicked
        /// </summary>
        public void Update()
        {
            mouse = Mouse.GetState();
            mouseBox.X = mouse.X;
            mouseBox.Y = mouse.Y;

            //System.Diagnostics.Debug.WriteLine(listDialogue.Count + " " + dListIndex);
            if (isShowing)
            {
                if (dListIndex < listDialogue.Count)
                {
                    currentDialogue = listDialogue[dListIndex].dialogue;
                    currentSpeaker = listDialogue[dListIndex].name;
                    System.Diagnostics.Debug.WriteLine("IN DV CURR SPEAKER:" + currentSpeaker);
                    //System.Diagnostics.Debug.WriteLine("size:" + listDialogue[dListIndex].optionList.Count);
                    if (dListIndex == listDialogue.Count)
                    {
                        System.Diagnostics.Debug.WriteLine("IN DLISTINDEX +_1");
                        continueButtonShowing = false;

                    }

                    if (listDialogue[dListIndex].optionList.Count > 0)
                    {

                        //System.Diagnostics.Debug.WriteLine("LIST DIALOGUE = NULL");
                        continueButtonShowing = false;
                        optionHandler();
                    }
                }
                else
                {
                    isShowing = false;
                    //planner.dialogueFinished = true;
                }
                if (mouse.LeftButton == ButtonState.Pressed && mouseBox.Intersects(continueRect) && mousePast.LeftButton == ButtonState.Released && continueButtonShowing)
                {
                    dListIndex++;
                    Mouse.SetPosition(0, 0);
                }
            }
            mousePast = mouse;


        }

        /// <summary>
        /// Checks which option was picked by the user
        /// </summary>
        private void optionHandler()
        {

            optionRect o = listOptionRect[0];
            for (int i = 0; i < o.optionRectangle.Count; i++)
            {
                //                System.Diagnostics.Debug.WriteLine("THERE IS A RECTANGLE"); 
                Rectangle r = o.optionRectangle[i];
                if (mouse.LeftButton == ButtonState.Pressed && mouseBox.Intersects(r) && mousePast.LeftButton == ButtonState.Released)
                {
                    dListIndex++;
                    continueButtonShowing = true;
                    listOptionRect.Remove(o);
                    eventPlanner.Initialize(o.nameOfTriggerer, o.optionName[i], o.typeOfTriggerer);

                    Mouse.SetPosition(0, 0);
                }
            }
        }

        /// <summary>
        /// Iterates the list of dialogue and modifies it in order to fit in the dialogue box
        /// </summary>
        public void modifyListDialogue()
        {
            Conversation c;
            dListIndex = 0;
            int i;
            for (i = 0; i < listDialogue.Count; i++)
            {
                c = listDialogue[i];
                c.dialogue = modifyText(c.dialogue);

                //if conversation has options
                if (c.optionList.Count > 0)
                {
                    int ctr = 0;
                    Vector2 temp;
                    optionRect opt = new optionRect();
                    opt.optionName = new List<string>();
                    opt.optionRectangle = new List<Rectangle>();

                    foreach (string o in c.optionList)
                    {
                        if (ctr == 0)
                            c.dialogue += "\n          " + o;
                        else
                            c.dialogue += "\n\n          " + o;

                        temp = calibri.MeasureString(o);
                        //opt.eventId.Add(o.idEvent);
                        opt.optionRectangle.Add(new Rectangle(315, 580 + (ctr * 70), (int)temp.X, (int)temp.Y));
                        opt.optionName.Add(o);
                        ctr++;
                    }
                    System.Diagnostics.Debug.WriteLine("IN DIALOGUE VIEW name of triggerer:" + c.nameOfTriggerer + " index: " + i);
                    opt.nameOfTriggerer = c.nameOfTriggerer;
                    opt.typeOfTriggerer = c.typeOfTriggerer;
                    listOptionRect.Add(opt);

                }

                listDialogue[i] = c;
            }
            //if (listDialogue[i - 1].type.Equals('I')) {
            //    inventGameFound = true;
            //  //  c = new Conversation("Alex", "Should I keep it? \n\n     Yes \n\n     No", 'T', null);
            //    //listDialogue.Add(c);
            //}
        }

        private string[] words;
        private StringBuilder actualSentence = new StringBuilder(), temp = new StringBuilder();
        private Vector2 tempStringRectangle; //width and height of the string
        private int ctr = 0; //ctr for number of indentions made 
        private const int DESCBOXWIDTH = 800;
        private const int DESCBOXHEIGHT = 250;

        /// <summary>
        /// Used by modifyListDialogue in order to modify the text
        /// </summary>
        /// <param name="s">String to be parsed and modified</param>
        /// <returns>Returns the modified string</returns>
        private string modifyText(string s)
        {
            actualSentence.Clear();
            temp.Clear();
            continueButtonShowing = true;
            inventGameFound = false;
            words = null;
            words = s.Split(new char[] { ' ' });
            ctr = 0;
            foreach (string w in words)
            {
                //System.Diagnostics.Debug.WriteLine(w);
                temp.Append(w + " ");
                tempStringRectangle = calibri.MeasureString(temp);
                if (tempStringRectangle.X - (DESCBOXWIDTH * ctr) > DESCBOXWIDTH)
                {
                    actualSentence.Append("\n" + w + " ");
                    ctr += 1;
                }
                else
                    actualSentence.Append(w + " ");

            }

            return actualSentence.ToString();

        }

        private int yOffsetArrow = 60;
        /// <summary>
        /// Draws the dialogue box, text and buttons
        /// </summary>
        /// <param name="spriteBatch"></param>
        public void Draw(SpriteBatch spriteBatch)
        {
            //spriteBatch.DrawString(calibri, mouse.X + " " + mouse.Y, new Vector2(50, 50), Color.Black);
            if (isShowing)
            {
                if (currentSpeaker == "Alex")
                {
                    spriteBatch.Draw(char1Pic, CHAR1POS, Color.White);
                }
                else {
                    spriteBatch.Draw(char1Pic, CHAR1POS, Color.Gray);
                }
               
                if (char2Pic != null && char2Pic.Name.ToLower().Contains(currentSpeaker.ToLower()))
                {
                    spriteBatch.Draw(char2Pic, CHAR2POS, Color.White);
                }
                else if(char2Pic != null){
                    spriteBatch.Draw(char2Pic, CHAR2POS, Color.Gray);
                }


                spriteBatch.Draw(leftBar, LEFTBARPOS, Color.White);
                spriteBatch.Draw(rightBar, RIGHTBARPOS, Color.White);
                spriteBatch.Draw(dialogueBox, DIALOGUEBOXPOS, Color.White);
                spriteBatch.Draw(namePlacer, NAMEPLACERPOS, Color.White);
                if (currentSpeaker != null)
                {
                    spriteBatch.DrawString(calibri, currentSpeaker, new Vector2(240, 485), Color.White);
                }
                spriteBatch.DrawString(calibri, currentDialogue, TEXTPOS, Color.Black);
                if (continueButtonShowing)
                    spriteBatch.Draw(continueButton, CONTINUEPOS, Color.White);
                if (dListIndex < listDialogue.Count)
                {
                    if (listDialogue[dListIndex].optionList.Count > 0)
                    {
                        System.Diagnostics.Debug.WriteLine("SHOWING ARROW");
                        ctr = 0;
                        foreach (string o in listDialogue[dListIndex].optionList)
                        {
                            if (o != " ")
                            {
                                spriteBatch.Draw(arrowButton, new Vector2(335 + calibri.MeasureString(o).X, 590 + yOffsetArrow * ctr), Color.White);
                                ctr++;
                            }
                        }
                    }
                } 
            }
        }
    }
}
